﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Filters;
using WqLunTan.Controllers;
using WqLunTan.DBContext;
using WqLunTan.Models.DataBase;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using System.IdentityModel.Tokens.Jwt;
using Microsoft.AspNetCore.Mvc;
using WqLunTan.Areas.Manage.Controllers;

namespace WqLunTan.Filters
{
    /// <summary>
    /// 权限验证, 默认为普通用户权限
    /// </summary>
    public class AuthAttribute : ActionFilterAttribute
    {

        /// <summary>
        /// 用户授权类型
        /// </summary>
        public WqUserAuth AuthType { get; set; } = WqUserAuth.User;

        /// <summary>
        /// 在action之前执行
        /// </summary>
        /// <param name="context"></param>
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            WqUser wqUser = null;
            if (context.Controller is Controller controller)
            {
                var session = context.HttpContext.Session;
                if (session.Keys.Contains("LoginUser"))
                {
                    wqUser = session.getValue<WqUser>("LoginUser");
                    if (wqUser.LoginTime.AddMinutes(30) < DateTimeOffset.UtcNow)
                    {
                        var db = context.HttpContext.RequestServices.GetService<MySqlDbContext>();
                        wqUser = db.Users.Where(x => x.Id == wqUser.Id).SingleOrDefault();    // 从数据库获取最新的用户
                        wqUser.LoginTime = DateTimeOffset.UtcNow;
                        db.SaveChanges();   // 保存最近一次会话的登录时间
                        session.setValue("LoginUser", wqUser);
                    }
                }
                else
                {
                    if (controller.User.Claims.Count(x => x.Type.Equals(JwtRegisteredClaimNames.Sid)) > 0)
                    {
                        var db = context.HttpContext.RequestServices.GetService<MySqlDbContext>();
                        var sid = controller.User.Claims.SingleOrDefault(x => x.Type.Equals(JwtRegisteredClaimNames.Sid));
                        var id = new Guid(sid.Value);
                        wqUser = db.Users.Where(x => x.Id == id).SingleOrDefault();    // 从数据库获取最新的用户
                        if (wqUser != null)
                        {
                            wqUser.LoginTime = DateTimeOffset.UtcNow;
                            session.setValue("LoginUser", wqUser);
                        }
                    }
                }

                if (wqUser == null)
                {
                    if (!context.HttpContext.Request.Headers.ContainsKey("X-Requested-With"))
                    {
                        context.Result = new RedirectResult("/");
                    }
                    else
                    {
                        context.Result = new JsonResult(new { msg = "error", data = "无权限或者未登录" }) { StatusCode = 403 };
                    }
                    return;
                }
                else if (wqUser.UserAuth.HasFlag(WqUserAuth.Admin) || wqUser.IsAdmin)
                {
                    // 拥有管理员权限, 不再检查其他权限
                }
                else if (!wqUser.Enable)
                {
                    if (!context.HttpContext.Request.Headers.ContainsKey("X-Requested-With"))
                    {
                        context.Result = new RedirectResult("/");
                    }
                    else
                    {
                        context.Result = new JsonResult(new { msg = "error", data = "您的账号已被禁止登录" }) { StatusCode = 403 };
                    }
                    return;
                }
                else if (!wqUser.UserAuth.HasFlag(AuthType))
                {
                    if (!context.HttpContext.Request.Headers.ContainsKey("X-Requested-With"))
                    {
                        context.Result = new RedirectResult("/");
                    }
                    else
                    {
                        context.Result = new JsonResult(new { msg = "error", data = "无权限或者未登录" }) { StatusCode = 403 };
                    }
                    return;
                }
                controller.ViewData["LoginUser"] = wqUser;
            }

            if (context.Controller is BaseController baseController)
            {
                baseController.LoginUser = wqUser;
            }

            if (context.Controller is BaseManageController manageController)
            {
                manageController.LoginUser = wqUser;
            }

            base.OnActionExecuting(context);
        }
    }
}
